<template>
  <div class="chat-container">
    <div style="text-align: center; color: deepskyblue; font-size: 20px">
      你好，我是图书推荐AI、作为你的智能伙伴，你可以向我提出关于图书的问题。
    </div>
    <el-card class="chat" style="height: 77vh; border-radius: 15px; border-color: #ccc">
      <el-card class="main_chat">
        <div v-for="item in messages" class="message">
          <div v-if="item.inputMessage != null && item.inputMessage !== ''" class="user-message">
            {{ item.inputMessage }}
          </div>
          <div v-if="item.aiResult != null && item.aiResult !== ''" class="bot-message">
            {{ item.aiResult }}
          </div>
        </div>
        <div class="box" v-if="isInputEnabled">
          <span></span>
          <span></span>
          <span></span>
        </div>
      </el-card>
      <el-input
        placeholder="Enter发送，请输入内容，例如：我喜欢动物类的书籍，请给我推荐"
        v-model.trim="inputMessage"
        size="large"
        :disabled="isInputEnabled"
        @keyup.enter.native="sendMessage"
      >
        <!-- <el-button @click="sendMessage">发送</el-button> -->
      </el-input>
    </el-card>
  </div>
</template>
<script setup>
import { ref, reactive, onMounted, onBeforeUnmount } from "vue";
import { getChat, postChat } from "../../api/api";
import { useSocket } from "../../utils/websocket";
import { userStore } from "../../store/UserStore";

const useStore = userStore();
const messages = reactive([]);
const inputMessage = ref("");
// const message = reactive({
//   inputMessage: "",
//   aiResult: "",
//   // userId:null
// });

let arr = "";
let timeout;
let lastMessageId;
const loading = ref(false);

let messageBuffer = "";
let typingIndex = 0; // 当前正在显示的字符索引
let timeoutId; // 存储定时器 ID
let currentMessage = ""; // 当前正在展示的消息

// 控制输入框是否可用
let isInputEnabled = ref(false);
const add = ref(false);
// 当前显示的字符索引
let typedIndex = 0;
// 是否正在输入的状态
let isTyping = false;
//webSocket
const { socket, send, on, off } = useSocket(
  `ws://8.148.4.43:8000/v1/user/chats?Authorization=${useStore.userToken}`
);

onMounted(() => {
  getHistoryRecords();
  // on("open", () => socket.send("Authorization: Bearer " + useStore.userToken));
  // on("close", () => console.log("Socket closed!"));
  //webSocket连接上服务器时
  on("open", event => {
    console.log("webSocket连接上服务器时", event);
  });
});
onBeforeUnmount(() => {
  on("close", () => console.log("Socket closed!"));
});

// on("error", error => {
//   console.error("WebSocket Error:", error);
// });
// on("close", event => {
//   console.log("Connection closed", event);
// });

const sendMessage = () => {
  // 将用户输入的消息添加到消息列表中
  if (inputMessage.value === "") {
    ElMessage.error("文本不能为空");
    return;
  }
  // 先判断文本内容是否为空或者是无意义的数字，如果是提示用户信息
  if (/[\da-zA-Z]/.test(inputMessage.value)) {
    ElMessage.error("请不要输入无意义的内容");
    return;
  }
  if (inputMessage.value !== "") {
    const sentData = {
      message: inputMessage.value,
    };
    send(JSON.stringify(sentData));
    isInputEnabled.value = true;
    // var userId = window.sessionStorage.getItem("userId");
    messages.push({
      id: Date.now(),
      inputMessage: inputMessage.value,
      // userId: parseInt(userId),
    });
    add.value = true;

    // // 这里可以是调用 GPT API 的逻辑
    // message.inputMessage = inputMessage.value.trim();
    // message.userId = userId;
    // // 清空输入框
    inputMessage.value = "";
    loading.value = true;

    ElMessage({
      message: "文本输入越长，接口调用时间越长，请耐心等待",
      type: "warning",
      duration: 2500,
    });

    //清空上次的聊天
    arr = "";
    loading.value = false;
  }
};

// socket.on("message", data => {
//   console.log("Received data:", data);
//   arr += data; // 累加接收到的数据

//   if (add.value == true && !isTyping) {
//     messages.push({
//       id: lastMessageId,
//       aiResult: " ",
//       // userId: parseInt(userId),
//     });
//     add.value = false;
//   }
//   console.log(messages[messages.length - 1]);
//   // 匹配 `{` 的正则表达式
//   const regex = /\{\"message\":\"end\"\}/;
//   // 返回所有匹配的结果  )
//   const matches = arr.match(regex);
//   if (matches == null) {
//     messages[messages.length - 1].aiResult = arr;
//     typeEffect(messages[messages.length - 1].aiResult); // 启动打字机效果
//     isInputEnabled.value = true;
//   } else {
//     isInputEnabled.value = false;
//   }
// });
// socket.on("message", data => {
//   console.log("Received data:", data);
//   arr += data; // 累加接收到的数据
//   if (add.value == true && !isTyping) {
//     messages.push({
//       id: lastMessageId,
//       aiResult: "", // 初始化为空，待打字机效果填充
//     });
//     // add.value = false;
//     typedIndex = 0; // 重置字符索引
//     typeEffect(arr); // 启动打字机效果
//   }

//   console.log(messages[messages.length - 1]);

//   const regex = /\{/g;
//   const matches = arr.match(regex);
//   if (matches == null) {
//     isInputEnabled.value = true;
//   } else {
//     isInputEnabled.value = false;
//   }
// });

function typeEffect(message) {
  if (typingIndex < message.length) {
    isTyping = true;
    timeoutId = setTimeout(() => {
      messages[messages.length - 1].aiResult += message.charAt(typingIndex);
      typingIndex++;
      typeEffect(message); // 递归调用
      isInputEnabled.value = false;
    }, 30); // 字符显示的间隔时间
  } else {
    isTyping = false;
    typingIndex = 0; // 重置字符索引
  }
}

// socket.on("message", data => {
//   console.log("Received data:", data);

//   messageBuffer += data; // 累加接收到的数据
//   // 检查消息是否结束
//   const endMessageIndex = messageBuffer.indexOf('{"message":"end"}');

//   if (endMessageIndex !== -1) {
//     // 提取结束标志之前的完整消息
//     const completeMessage = messageBuffer.slice(0, endMessageIndex);
//     messageBuffer = messageBuffer.slice(endMessageIndex + '{"message":"end"}'.length); // 更新缓冲区，去掉已处理的消息

//     if (add.value == true && !isTyping) {
//       messages.push({
//         id: lastMessageId,
//         aiResult: "", // 初始化为空，待打字机效果填充
//       });
//       add.value = false; // 处理完成
//       typingIndex = 0; // 重置字符索引

//       // 显示完整消息的打字机效果
//       typeEffect(completeMessage);
//     }
//   }
// });

socket.on("message", data => {
  let dataloading = false; // 初始化加载状态
  console.log("Received data:", data);

  if (data) {
    messageBuffer += data; // 累加接收到的数据

    // 检查消息是否结束
    const endMessageIndex = messageBuffer.indexOf('{"message":"end"}');

    if (endMessageIndex !== -1) {
      // 提取结束标志之前的完整消息
      const completeMessage = messageBuffer.slice(0, endMessageIndex);
      messageBuffer = messageBuffer.slice(endMessageIndex + '{"message":"end"}'.length); // 更新缓冲区
      if (dataloading) {
        // 如果之前是加载状态，则取消加载状态
        dataloading = false;
        // 这里可以取消加载动画
        console.log("Loading complete");
      }
      if (add.value == true && !isTyping) {
        messages.push({
          id: lastMessageId,
          aiResult: "", // 初始化为空，待打字机效果填充
        });
        add.value = false; // 处理完成
        typingIndex = 0; // 重置字符索引

        // 显示完整消息的打字机效果
        typeEffect(completeMessage);
      }
    } else {
      // 如果没有找到结束标志，设置加载状态
      if (!dataloading) {
        dataloading = true;
        // messages.push({
        //   id: 99,
        //   loading: "123", // 初始化为空，待打字机效果填充
        // });
        // 这里可以显示加载动画，比如一个旋转的图标
        console.log("Loading...");
      }
    }
  }
});

/**
 * 获取最近五条该用户和AI交流的信息
 */
const getHistoryRecords = () => {
  // postChat();
  // .then(res => {
  //   res.data.forEach(item => {
  //     messages.push(item);
  //   });
  //   ElMessage({
  //     message: "获取信息成功",
  //     type: "success",
  //   });
  // })
  // .catch(err => {
  //   console.log(err, "err");
  //   ElMessage.error("获取信息失败");
  // });
};
</script>

<style scoped lang="less">
.main_chat {
  background: url("../../assets/image/bg2.jpg") no-repeat center center;
  margin-bottom: 10px;
  height: 66vh;
  background-size: cover;
  border-radius: 10px;
  overflow-y: scroll;
}

.message {
  display: flex;
  flex-direction: column;
}

.user-message {
  display: flex;
  flex-direction: row;
  background-color: #e7f7ff;
  padding: 10px;
  border-radius: 10px;
  align-self: flex-end;
  text-align: right;
  margin-top: 10px;
}

.bot-message {
  background-color: #f4f6f8;
  padding: 10px;
  border-radius: 10px;
  text-align: left;
  align-self: flex-start;
  margin-top: 10px;
  white-space: pre-wrap;
}

.box {
  padding: 10px;
  border-radius: 10px;
  text-align: left;
  align-self: flex-start;
  margin-top: 10px;
  white-space: pre-wrap;
  display: flex;
}

.box span {
  // position: absolute;

  width: 18px;
  height: 18px;
  background: #dfd6d6;
  opacity: 0;
  border-radius: 100%;
  animation: anim 1s infinite ease-in-out;
}

.box > :nth-child(2) {
  animation-delay: 0.2s;
}

.box > :nth-child(3) {
  animation-delay: 0.4s;
}

@keyframes anim {
  0% {
    opacity: 0.3;
    transform: translateY(0px);
  }
  50% {
    opacity: 1;
    transform: translateY(-10px);
    background: #656466;
  }
  100% {
    opacity: 0.3;
    transform: translateY(0px);
  }
}
</style>
